<?php

namespace Sc\Util\HtmlStructure\Theme\ElementUI;

use App\Common\Util\TP;
use plugins\UEditorPlus\Admin\Controller\UEditorController;
use Sc\Util\HtmlElement\El;
use Sc\Util\HtmlElement\ElementType\AbstractHtmlElement;
use Sc\Util\HtmlElement\ElementType\DoubleLabel;
use Sc\Util\HtmlStructure\Form\FormItemAttrGetter;
use Sc\Util\HtmlStructure\Form\FormItemEditor;
use Sc\Util\HtmlStructure\Html\Html;
use Sc\Util\HtmlStructure\Html\Js;
use Sc\Util\HtmlStructure\Html\Js\JsCode;
use Sc\Util\HtmlStructure\Html\Js\JsFunc;
use Sc\Util\HtmlStructure\Html\Js\JsVar;
use Sc\Util\HtmlStructure\Theme\Interfaces\FormItemEditorThemeInterface;

/**
 * Class FormItemEditorTheme
 */
class FormItemEditorTheme extends AbstractFormItemTheme implements FormItemEditorThemeInterface
{
    const RESOURCE_DIR = '/static/ueditor/';

    const ALL_JS = self::RESOURCE_DIR . 'ueditor.all.js';
    const CONFIG_JS = self::RESOURCE_DIR . 'ueditor.config.js';
    const PARSE_JS = self::RESOURCE_DIR . 'ueditor.parse.js';


    public function renderFormItem($formItem): AbstractHtmlElement
    {
        $this->resourceLoad();
        $editorEl = $this->initialize($formItem);
        $baseEl   = $this->getBaseEl($formItem);

        return $baseEl->append($editorEl);
    }

    private function initialize(FormItemEditor|FormItemAttrGetter $formItemEditor): DoubleLabel
    {
        $editorVarName = 'editor_' . $formItemEditor->getFormModel() . "_" . $formItemEditor->getName();
        $formVarName   = "VueApp." . "{$this->getVModel($formItemEditor)}";
        $id = 'editor-' . $formItemEditor->getFormModel() . "-" . $formItemEditor->getName();
        $el = El::double('div')->setId($id)->setAttrs([
            'style' => 'width:100%;',
        ]);
        Html::js()->vue->set('UE', '@UE');

        $initOption = $formItemEditor->getInitOptions();

        $eventHandle = [];
        foreach ($initOption['event'] ?? [] as $event => $code) {
            $eventHandle[] = JsFunc::call("$editorVarName.addListener", $event, JsFunc::arrow()->code($code));
        }

        $formItemEditor->getForm()?->setSubmitHandle(
            JsCode::create("$formVarName = this.$editorVarName?.getContent()")
        );

        Html::js()->vue->addMethod($editorVarName . 'Render', JsFunc::anonymous()->code(
            Js\JsIf::when("!document.getElementById('$id')")->then(
                JsCode::create('return;')
            ),
            JsVar::def($editorVarName, JsFunc::call("this.UE.getEditor", $id, [
                'UEDITOR_HOME_URL'   => self::RESOURCE_DIR,
                'UEDITOR_CORS_URL'   => self::RESOURCE_DIR,
                ...$this->defaultToolbars(),
                ...$initOption,
                'initialFrameHeight' => $initOption['initialFrameHeight'] ?? 350,
                'initialFrameWidth'  => $initOption['initialFrameHeight'] ?? '100%',
                'fullScreen'         => (bool)$formItemEditor->getFullScreen(),
                'serverUrl'          => (string)($initOption['serverUrl'] ?? TP::route()->to([UEditorController::class, 'index'])),
            ])),
            JsVar::assign("this.$editorVarName", "@$editorVarName"),
            JsCode::create("$editorVarName.ready(() => $editorVarName.setContent($formVarName))"),
            ...$eventHandle,
        ));

        Html::js()->vue->event('mounted', JsCode::make(
            JsFunc::call("this.{$editorVarName}Render")
        ));

        return $el;
    }

    private function resourceLoad(): void
    {
        Html::js()->load(self::CONFIG_JS);
        Html::js()->load(self::ALL_JS);
    }

    private function defaultToolbars(): array
    {
        return [
            'toolbars' => [
                [
                    "fullscreen",   // 全屏
                    "source",       // 源代码
                    "|",
                    "undo",         // 撤销
                    "redo",         // 重做
                    "|",
                    "bold",         // 加粗
                    "italic",       // 斜体
                    "underline",    // 下划线
                    "fontborder",   // 字符边框
                    "strikethrough",// 删除线
                    "superscript",  // 上标
                    "subscript",    // 下标
                    "removeformat", // 清除格式
                    "autotypeset",  // 自动排版
                    "blockquote",   // 引用
                    "pasteplain",   // 纯文本粘贴模式
                    "|",
                    "forecolor",    // 字体颜色
                    "backcolor",    // 背景色
                    "insertorderedlist",   // 有序列表
                    "insertunorderedlist", // 无序列表
                    "|",
                    "customstyle",         // 自定义标题
                    "paragraph",           // 段落格式
                    "fontfamily",          // 字体
                    "fontsize",            // 字号
                    "|",
                    "indent",              // 首行缩进
                    "justifyleft",         // 居左对齐
                    "justifycenter",       // 居中对齐
                    "justifyright",
                    "justifyjustify",      // 两端对齐
                    "lineheight",          // 行间距
                    "|",
                    "link",                // 超链接
                    "simpleupload",        // 单图上传
                    "insertimage",         // 多图上传
                    "scrawl",              // 涂鸦
                    "attachment",          // 附件
                    "insertcode",          // 插入代码
                    "background",          // 背景
                    "formula",             // 公式
                    "|",
                    "horizontal",          // 分隔线
                    "spechars",            // 特殊字符
                    "inserttable",         // 插入表格
                    "|",
                    "searchreplace",       // 查询替换
                    "help",                // 帮助
                ]
            ]
        ];
    }
}